home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Games / Tetris / Source / Minimatrix.m < prev    next >
Text File  |  1975-04-26  |  6KB  |  239 lines

  1. /*
  2.  * This is the view from which NextMatrix and TetMatrix inherit.
  3.  *
  4.  *  The major data structures are.
  5.  *   id *iconMatrix;  Holds the id of the block that is in the current
  6.  *                    (row, column).
  7.  */
  8. #import <appkit/NXImage.h>
  9. #import <appkit/nextstd.h>
  10. #import <dpsclient/psops.h>
  11. #import "Minimatrix.h"
  12.  
  13. @implementation Minimatrix
  14.  
  15. - initFrame:(const NXRect *)frameRect
  16. {
  17.     return [self initFrame:frameRect bitmap:nil numRows:0 numCols:0];
  18. }
  19.  
  20. - initFrame:(const NXRect *)frameRect
  21.             numRows:(int)rowsHigh numCols:(int)colsWide
  22. {
  23.     return [self initFrame:frameRect
  24.             bitmap:nil
  25.             numRows:rowsHigh numCols:colsWide];
  26. }
  27.  
  28. - initFrame:(const NXRect *)frameRect
  29.        bitmap:theBitmap numRows
  30.         :(int)rowsHigh numCols
  31.         :(int)colsWide
  32. {
  33.     [super initFrame:frameRect];
  34.  
  35.     numRows = rowsHigh;
  36.     numCols = colsWide;
  37.     NX_MALLOC(iconMatrix, id, numRows * numCols);
  38.     backgroundGray = NX_LTGRAY;
  39.     inset.width = inset.height = 0.0;
  40.     insetBounds = bounds;
  41.     intercell = elementSize = inset;
  42.  
  43.     [self setBitmap:theBitmap];
  44.     return self;
  45. }
  46.  
  47. /*
  48.  * Return the id of the bitmap at (row,column) if one exists, else nil.
  49.  */
  50. - bitmapAt:(int)row :(int)column
  51. {
  52.     return (row < 0 || column < 0 || row >= numRows || column >= numCols) ?
  53.       nil : *(iconMatrix + row * numCols + column);
  54. }
  55.  
  56. - displayAt:(int)row :(int)column
  57. {
  58.     NXRect destRect;
  59.  
  60.     NXSetRect(&destRect,
  61.                  inset.width + column * (intercell.width + elementSize.width),
  62.                  inset.height + row * (intercell.width + elementSize.width),
  63.                  elementSize.width + intercell.width,
  64.                  elementSize.height + intercell.height);
  65.  
  66.     return [self display:&destRect :1];
  67. }
  68.  
  69. - drawSelf:(const NXRect *)rects :(int)rectCount
  70. {
  71.     int rowc, colc;
  72.     int rectc;
  73.     NXRect destRect;
  74.     id *iconMatrixPiece;
  75.     const NXRect *rectp;
  76.     static int bsides[] = {NX_YMIN, NX_XMAX, NX_YMAX, NX_XMIN,
  77.                                   NX_YMIN, NX_XMAX, NX_YMAX, NX_XMIN};
  78.  
  79.     static float bgrays[] = {NX_WHITE, NX_WHITE, NX_DKGRAY, NX_DKGRAY,
  80.                                      NX_LTGRAY, NX_WHITE, NX_DKGRAY, NX_DKGRAY};
  81.  
  82.     PSsetgray(backgroundGray);
  83.     NXRectFillList(rects, rectCount); // Clear old areas
  84.  
  85.     destRect = bounds;
  86.  
  87.     // Draw the insetRect around the border of the game when a Piece
  88.     // intersects with the border.
  89.  
  90.     if ((inset.width || inset.height) && !NXContainsRect(&insetBounds, rects)) {
  91.         NXDrawTiledRects(&destRect, (NXRect *)0, bsides, bgrays, 8);
  92.     }
  93.  
  94.     NXSetRect(&destRect, inset.width + intercell.width,
  95.                  inset.height + intercell.height,
  96.                  elementSize.width, elementSize.height);
  97.  
  98.     iconMatrixPiece = iconMatrix;
  99.  
  100.     // Redraw all of the Pieces that have changed
  101.     for (rowc = 0; rowc < numRows; rowc++) {
  102.         for (colc = 0; colc < numCols; colc++) {
  103.             if (*iconMatrixPiece) {
  104.                 rectc = rectCount;
  105.                 rectp = rects;
  106.                 while (rectc--) {
  107.                     if (NXIntersectsRect(&destRect, rectp++)) {
  108.                         // If we assume the piece contains no alpha then we could use
  109.                         // NX_COPY
  110.                         [*iconMatrixPiece composite:NX_SOVER toPoint:&destRect.origin];
  111.                         break;
  112.                     }
  113.                 }
  114.             }
  115.             // Add block's width + space b/w each block to get new X coord
  116.             destRect.origin.x += elementSize.width + intercell.width;
  117.             iconMatrixPiece++;      // Do next column in iconMatrix
  118.         }
  119.         destRect.origin.x = inset.width + intercell.width;
  120.  
  121.         // Add the block's height + intercell.height
  122.         destRect.origin.y += elementSize.height + intercell.height;
  123.     }
  124.     return self;
  125. }
  126.  
  127. /*
  128.  * Private method.
  129.  */
  130. - getIntercell:(NXSize *)aSize
  131. {
  132.     *aSize = intercell;
  133.     return self;
  134. }
  135.  
  136. - getRect:(NXRect *)theRect for:(int)row :(int)column
  137. {
  138.     theRect->size = elementSize; // Get block's image size
  139.     return [self point:&theRect->origin for:row :column];
  140. }
  141.  
  142. /*
  143.  * Calculate the TetrisView coordinate given the Tetrix (row,column)
  144.  */
  145. - point:(NXPoint *)thePoint for:(int)row :(int)column
  146. {
  147.     thePoint->x = inset.width + (column + 1) * intercell.width +
  148.       column * elementSize.width;
  149.     thePoint->y = inset.height + (row + 1) * intercell.height +
  150.       row * elementSize.height;
  151.     return self;
  152. }
  153.  
  154.  
  155. - setBackgroundGray:(float)gray
  156. {
  157.     backgroundGray = gray;
  158.     return self;
  159. }
  160.  
  161. - setBitmap:theBitmap
  162. {
  163.     id *iconMatrixPiece;
  164.  
  165. #ifdef DEBUG
  166.     printf("setBitmap\n");
  167. #endif
  168.  
  169.     iconMatrixPiece = iconMatrix + numRows * numCols;
  170.     while (iconMatrixPiece > iconMatrix)
  171.       *--iconMatrixPiece = theBitmap;
  172.     
  173.     if (theBitmap)
  174.       [theBitmap getSize:&elementSize];
  175.     return self;
  176. }
  177. /*
  178.  * Set the current (row, column) of the iconMatrix equal to the id of
  179.  * the block that was just dropped.
  180.  *
  181.  * There is a bug in this program.  Occasionally, an invalid row
  182.  * is generated.
  183.  *
  184.  * theBitmap row, col = (24, 6)
  185.  * theBitmap row, col = (23, 6)
  186.  * theBitmap row, col = (23, 7)
  187.  * theBitmap row, col = (25, 3)
  188.  * theBitmap row, col = (698590, 3)
  189.  */
  190. - setBitmap:theBitmap at:(int)row :(int)column
  191. {
  192.     if (row < numRows && row >= 0 && column < numCols && column >= 0) {
  193.         *(iconMatrix + row * numCols + column) = theBitmap;
  194.     } else {
  195.         fprintf(stderr, "Invalid row %d in Minimatrix::setBitmap\n", row);
  196.     }
  197.     return self;
  198. }
  199.  
  200.  
  201. /*
  202.  *  The size of the image (TIFF or PS) we are using to build the block.
  203.  *  Currently 16x16 is the image size.
  204.  */
  205. - setElementSize:(const NXSize *)aSize
  206. {
  207.     elementSize = *aSize;
  208.     return self;
  209. }
  210.  
  211. /*
  212.  * Set the number of pixels away from the border the pieces will be.
  213.  */
  214. - setInset:(const NXSize *)aSize
  215. {
  216.     inset = *aSize;
  217.     insetBounds = bounds;
  218.     NXInsetRect(&insetBounds, inset.width, inset.height);
  219.     return self;
  220. }
  221.  
  222. /*
  223.  * Set the amount of space to leave between each cell.
  224.  */
  225. - setIntercell:(const NXSize *)aSize
  226. {
  227.     intercell = *aSize;
  228.     return self;
  229. }
  230.  
  231. - free
  232. {
  233.     NX_FREE(iconMatrix);
  234.     return [super free];
  235. }
  236.  
  237. @end
  238.  
  239.